<body>
  <!-- 演示双向绑定（数据影响视图，视图影响数据） -->
  <input id="oInput" type="text">
  <p id="oP"></p>
</body>
<script>
const data = {
  name: '吕布',
  age: 18,
};

const copyData = { ...data }

// 劫持 data 中的数据属性（数据劫持），一旦被劫持了，就给我操作数据提供了契机（例如修改视图的契机）
Object.keys(data).forEach(key => {
  Object.defineProperty(data, key, {
    get() {
      return copyData[key]
    },
    set(newValue) {
      // #2 一旦给 name 赋值代码走这儿
      copyData[key] = newValue
      // #3 修改视图
      oP.innerHTML = newValue
      oInput.value = newValue
    }
  })
})

oInput.oninput = function(e) {
  // #1 一旦输入代码走这儿给 name 赋值
  data.name = e.target.value
}
</script>
